home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / sysdeps / unix / sparc / start.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-18  |  4.8 KB  |  180 lines

  1. /* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <errno.h>
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <fcntl.h>
  24.  
  25. #ifndef NO_SHLIB
  26. #include <sys/exec.h>
  27. #include <sys/types.h>
  28. #include <sys/mman.h>
  29. #include <link.h>
  30. #include <syscall.h>
  31. #endif
  32.  
  33. #if !defined (__GNUC__) || __GNUC__ < 2
  34.   #error This file uses GNU C extensions; you must compile with GCC version 2.
  35. #endif
  36.  
  37. /* The first piece of initialized data.  */
  38. int __data_start = 0;
  39.  
  40. VOLATILE int errno;
  41.  
  42. #ifndef    HAVE_GNU_LD
  43. #undef    environ
  44. #define    __environ    environ
  45. #endif
  46.  
  47. char **__environ;
  48.  
  49. extern void EXFUN(__libc_init, (int argc, char **argv, char **envp));
  50. extern int EXFUN(main, (int argc, char **argv, char **envp));
  51.  
  52. register long int sp asm("%sp"), fp asm("%fp");
  53.  
  54. #ifndef NO_SHLIB
  55. static void EXFUN(init_shlib, (NOARGS));
  56. #endif
  57.  
  58. #ifndef NO_EXPLICIT_START
  59. /* Declare _start with an explicit assembly symbol name of `start'
  60.    (note no leading underscore).  This is the name Sun's crt0.o uses,
  61.    and programs are often linked with `ld -e start'.  */
  62. void _start (void) asm ("start");
  63. #endif
  64.  
  65. void
  66. _start (void)
  67. {
  68.   /* It is important that these be declared `register'.
  69.      Otherwise, when compiled without optimization, they are put on the
  70.      stack, which loses completely after we zero the FP.  */
  71.   register int argc;
  72.   register char **argv, **envp;
  73.  
  74.   /* Unwind the frame built when we entered the function.  */
  75.   asm("restore");
  76.  
  77.   /* And clear the frame pointer.  */
  78.   fp = 0;
  79.  
  80.   /* The argument info starts after one register
  81.      window (64 bytes) past the SP.  */
  82.   argc = ((int *) sp)[16];
  83.   argv = (char **) &((int *) sp)[17];
  84.   envp = &argv[argc + 1];
  85.   __environ = envp;
  86.  
  87. #ifndef NO_SHLIB
  88.   init_shlib ();
  89. #endif
  90.  
  91.   /* Allocate 24 bytes of stack space for the register save area.  */
  92.   sp -= 24;
  93.   __libc_init (argc, argv, envp);
  94.  
  95.   exit (main (argc, argv, envp));
  96. }
  97.  
  98. #ifndef NO_SHLIB
  99.  
  100. /* System calls for use by the bootstrap routine.
  101.    These are defined here since the usual calls may be dynamically linked.  */
  102.  
  103. int syscall (int sysno, ...) asm ("init_syscall");
  104. asm ("init_syscall:\n"
  105.      "    clr %g1\n"
  106.      "    ta 0\n"
  107.      "    bcc 1f\n"
  108.      "    sethi %hi(_errno), %g1\n"
  109.      "    st %o0, [%g1 + %lo(_errno)]\n"
  110.      "    sub %g0, 1, %o0\n"
  111.      "1:retl\n"
  112.      "    nop");
  113.  
  114. static void
  115. DEFUN_VOID(init_shlib)
  116. {
  117.   extern struct link_dynamic _DYNAMIC;
  118.   int so, zf;
  119.   caddr_t somap;
  120.   caddr_t sodmap;
  121.   caddr_t sobssmap;
  122.   void (*ldstart) (int, int);
  123.   struct exec soexec;
  124.   struct 
  125.     {
  126.       caddr_t crt_ba;
  127.       int crt_dzfd;
  128.       int crt_ldfd;
  129.       struct link_dynamic *crt_dp;
  130.       char **crt_ep;
  131.       caddr_t crt_bp;
  132.     } soarg;
  133.   
  134.   /* If not dynamically linked, do nothing.  */
  135.   if (&_DYNAMIC == 0)
  136.     return;
  137.  
  138.   /* Map in the dynamic linker.  */
  139.   so = syscall (SYS_open, "/usr/lib/ld.so", O_RDONLY);
  140.   if (syscall (SYS_read, so, &soexec, sizeof (soexec)) != sizeof (soexec)
  141.       || soexec.a_magic != ZMAGIC)
  142.     {
  143.       static CONST char emsg[] = "crt0: no /usr/lib/ld.so\n";
  144.       
  145.       syscall (SYS_write, 2, emsg, sizeof (emsg) - 1);
  146.       syscall (SYS_exit, 127);
  147.     }
  148.   somap = (caddr_t) syscall (SYS_mmap, 0,
  149.                  soexec.a_text + soexec.a_data + soexec.a_bss,
  150.                  PROT_READ | PROT_EXEC, _MAP_NEW | MAP_PRIVATE,
  151.                  so, 0);
  152.   sodmap = (caddr_t) syscall (SYS_mmap, somap + soexec.a_text, soexec.a_data,
  153.                   PROT_READ | PROT_WRITE | PROT_EXEC,
  154.                   _MAP_NEW | MAP_FIXED | MAP_PRIVATE,
  155.                   so, soexec.a_text);
  156.   zf = syscall (SYS_open, "/dev/zero", O_RDONLY);
  157.   if (soexec.a_bss != 0)
  158.     sobssmap = (caddr_t) syscall (SYS_mmap,
  159.                   somap + soexec.a_text + soexec.a_data,
  160.                   soexec.a_bss,
  161.                   PROT_READ | PROT_WRITE | PROT_EXEC,
  162.                   _MAP_NEW | MAP_FIXED | MAP_PRIVATE,
  163.                   zf, 0);
  164.  
  165.   /* Call the entry point of the dynamic linker.  */
  166.   soarg.crt_ba = somap;
  167.   soarg.crt_dzfd = zf;
  168.   soarg.crt_ldfd = so;
  169.   soarg.crt_dp = &_DYNAMIC;
  170.   soarg.crt_ep = __environ;
  171.   soarg.crt_bp = (caddr_t) &&retaddr;
  172.   
  173.   ldstart = (__typeof (ldstart)) (somap + soexec.a_entry);
  174.   (*ldstart) (1, (char *) &soarg - (char *) sp);
  175.  
  176.  retaddr:
  177. }
  178.  
  179. #endif
  180.